#ifndef SYSCALL_H
#define SYSCALL_H

#define syscall1(call_num, arg1, res1, success) \
__asm__ __volatile__("int $64" \
				: "=a" (res1), "=d" (success) \
				: "a" (arg1), "d" (call_num) \
				: "ebx", "ecx", "esi", "edi" \
				);
#define syscall2(call_num, arg1, arg2, res1, res2, success) \
__asm__ __volatile__("int $64" \
				: "=a" (res1), "=b" (res2), "=d" (success) \
				: "a" (arg1), "b" (arg2), "d" (call_num) \
				: "ecx", "esi", "edi" \
				);
#define syscall3(call_num, arg1, arg2, arg3, res1, res2, res3, success) \
__asm__ __volatile__("int $64" \
				: "=a" (res1), "=b" (res2), "=c" (res3), "=d" (success) \
				: "a" (arg1), "b" (arg2), "c" (arg3), "d" (call_num) \
				: "esi", "edi" \
				);
#define syscall4(call_num, arg1, arg2, arg3, arg4, res1, res2, res3, res4, success) \
__asm__ __volatile__("int $64" \
				: "=a" (res1), "=b" (res2), "=c" (res3), "=S" (res4), "=d" (success) \
				: "a" (arg1), "b" (arg2), "c" (arg3), "S" (arg4), "d" (call_num) \
				: "edi" \
				);
#define syscall5(call_num, arg1, arg2, arg3, arg4, arg5, res1, res2, res3, res4, res5, success) \
__asm__ __volatile__("int $64" \
				: "=a" (res1), "=b" (res2), "=c" (res3), "=S" (res4), "=D" (res5), "=d" (success) \
				: "a" (arg1), "b" (arg2), "c" (arg3), "S" (arg4), "D" (arg5), "d" (call_num) \
				);

#define SYSCALL_MAX				256

#define SYS_EXIT					0x00
#define SYS_EXEC					0x01
#define SYS_LEVEL					0x02
#define SYS_SLEEP					0x03

#define SYS_CPU_INFO				0x04
#define SYS_MEM_INFO				0x05
#define SYS_TIME_INFO			0x06
									// 0x07

#define SYS_OPEN					0x08
#define SYS_CLOSE					0x09
#define SYS_READ					0x0A
#define SYS_WRITE					0x0B
#define SYS_READDIR				0x0C
#define SYS_FINDDIR				0x0D
									// 0x0E
									// 0x0F

#define SYS_PAGE_ALLOC			0x10
#define SYS_PAGE_FREE		 	0x11
									//	0x12
									//	0x13

#define SYS_POWER_STATE			0x14
									// 0x15
									// 0x16
									// 0x17

#define SYS_DISPLAY_RESET		0x18
#define SYS_DISPLAY_COLOR		0x19
#define SYS_DISPLAY_CURSOR 	0x1A
#define SYS_DISPLAY_POINTER	0x1B

#define SYS_KBD_LEDS				0x1C
									// 0x1D
									// 0x1E
									// 0x1F

typedef struct
{
	unsigned int arg1;
	unsigned int arg2;
	unsigned int arg3;
	unsigned int arg4;
	unsigned int arg5;
	unsigned int call;

	unsigned int res1;
	unsigned int res2;
	unsigned int res3;
	unsigned int res4;
	unsigned int res5;
	unsigned int success;
}syscall_regs_t;

void init_syscall();
int install_syscall(unsigned int syscall_number, void (*handler)(syscall_regs_t *r));

#endif
